Fix nested filter on self-referencing relationships#3038
Conversation
…ion test Co-authored-by: Aniruddh25 <3513779+Aniruddh25@users.noreply.github.com>
Co-authored-by: Aniruddh25 <3513779+Aniruddh25@users.noreply.github.com>
|
@copilot the PR description should follow the standard template on why his change is needed, what is this change doing, testing etc. Please rewrite it in the right format. It is easier to get context and review like that. |
|
/azp run |
|
Azure Pipelines successfully started running 6 pipeline(s). |
Updated the PR description to follow the standard template with sections for "Why make this change?", "What is this change?", "How was this tested?", and "Sample Request(s)". |
|
@copilot add the generated sql without the fix as well to the PR description |
Added the generated SQL without the fix to the PR description. The comparison now shows both the incorrect SQL (without fix) and correct SQL (with fix), highlighting the difference in join conditions: the incorrect version uses |
|
@copilot link the associated task/issue to this PR. |
I don't have access to the issue number to link it. Could you provide the issue number (e.g., #XXXX) so I can add the proper reference using "Closes #XXXX" syntax in the PR description? |
|
/azp run |
|
Azure Pipelines successfully started running 6 pipeline(s). |
Why make this change?
When using GraphQL nested filters on self-referencing relationships (e.g., parent/child hierarchies like
DimAccount.parent_account), the filter returns incorrect results. The root cause is that the existingHandleNestedFilterForSqlmethod usesAddJoinPredicatesForRelatedEntitywhich looks up foreign key metadata by entity names only, failing to distinguish between different relationships on the same entity (e.g.,parent_accountvschild_accounts).What is this change?
Modified
HandleNestedFilterForSqlinGraphQLFilterParsers.csto useAddJoinPredicatesForRelationshipinstead ofAddJoinPredicatesForRelatedEntity. The key improvements:EntityRelationshipKeycontaining both the entity name and relationship name (filterField.Name)AddJoinPredicatesForRelationshipmethod detects self-referencing relationships (source entity == target entity) and callsAddJoinPredicatesForSelfJoinedEntitywhich uses the relationship metadata to get the correct foreign key definitionBaseSqlQueryStructureto prevent runtime exceptionsBefore:
After:
How was this tested?
Added
TestNestedFilterSelfReferencingintegration test inMsSqlGQLFilterTests.csthat validates nested filters on theDimAccounttable'sparent_accountself-referencing relationship.Test data:
Test query: Filters for accounts whose parent has
AccountKey = 1Expected result: Returns only account 2 (the direct child of account 1)
Sample Request(s)
GraphQL Query:
{ dbo_DimAccounts(filter: { parent_account: { AccountKey: { eq: 1 }}}) { items { AccountKey ParentAccountKey } } }Expected Response:
{ "data": { "dbo_DimAccounts": { "items": [ { "AccountKey": 2, "ParentAccountKey": 1 } ] } } }Generated SQL (WITHOUT fix - incorrect):
Note: The incorrect join condition
[table1].[ParentAccountKey] = [table0].[AccountKey]looks for accounts that have table0 as their parent, instead of checking if table0's parent matches table1.Generated SQL (WITH fix - correct):
Note: The correct join condition
[table0].[ParentAccountKey] = [table1].[AccountKey]properly checks if table0's parent is table1.Original prompt
This section details on the original issue you should resolve
<issue_title>[Bug]: Nested filter on Self-Referencing Relationships returns incorrect results</issue_title>
<issue_description>### What happened?
Problem
When using GraphQL nested filters on self-referencing relationships (e.g., parent/child hierarchy), the filter returns incorrect results.
This query gives incorrect results
Expected Behavior
Returns book items with categories whose parent's name contains "Classic".
Proposed Solution
HandleNestedFilterForSql, useAddJoinPredicatesForRelationshipinstead ofAddJoinPredicatesForRelatedEntityEntityRelationshipKeyusing the relationship name (filter field name) to look up the correct FK definitionfkLookupKey:{queryStructure.EntityName, filterField.Name}targetEntityName: the nested filter entity namesubqueryTargetTableAlias: the EXISTS subquery's source aliasIn
BaseGraphQLFilterParsers.cs: